#include <stdio.h>
#include <stdlib.h>
#include"../common/util.h"
#undef __HAVE_DISTINCT_FLOAT128
#include <math.h>
#include <time.h>
#include <obliv.h>
#include"kmeans.h"
#include <assert.h>
#include <unistd.h>

ProtocolDesc pd;
protocolIO io;
int K,N,D;  //聚类的数目，数据量，数据的维数
float **data;  //存放数据
int *in_cluster;  //标记每个点属于哪个聚类
float **cluster_center;  //存放每个聚类的中心点
float **loadData1(int *k,int *d,int *n);//导入数据
float **loadData2(int *k,int *d,int *n);//导入数据
float s1();
float s2();
float b0=1.0;
float b1=1.0;//随机值
//重构需要交互的值
//float Xs0[2][2];
//float Ys0[2][2];
float Xs1[2][2];
float Ys1[2][2];
float Xs[2][2];
float Ys[2][2];
int  main(int argc,char *argv[])
{
    int i,j;
    /**srand((unsigned int)(time(NULL)));  //随机初始化k个中心点
    b0=rand();//b0
    b1=rand();//b1**/
    protocolUseStdio(&pd); 
    const char* remote_host = (strcmp(argv[2],"--")?argv[2]:NULL);
    ocTestUtilTcpOrDie(&pd,remote_host,argv[1]);
    //protocolUseStdio(&pd);
    int currentParty = (remote_host?2:1);
    //setCurrentParty(&pd,argv[1][0]=='1'?1:2);
    if(currentParty==1){
    	s1();
    }else if(currentParty==2){       
    	s2();
    }
    setCurrentParty(&pd,currentParty);
    execYaoProtocol(&pd,kmeansdata,&io);
    cleanupProtocol(&pd);
    return 0;
}
//动态创建二维数组
float **array(int m,int n)
{
    int i;
    float **p;
    p=(float **)malloc(m*sizeof(float *));
    p[0]=(float *)malloc(m*n*sizeof(float));
    for(i=1;i<m;i++)    p[i]=p[i-1]+n;
    return p;
}
void freearray(float **p)
{
    free(*p);
    free(p);
}
float **loadData1(int *k,int *d,int *n)
{
    int i,j;
    float **arraydata;
    FILE *fp;
    if((fp=fopen("txt1.txt","r"))==NULL)    fprintf(stderr,"cannot open data.txt!\n");
    if(fscanf(fp,"K=%d,D=%d,N=%d\n",k,d,n)!=3)        fprintf(stderr,"load error!\n");
    arraydata=array(*n,*d);  //生成数据数组
    cluster_center=array(*k,*d);  //聚类的中心点
    in_cluster=(int *)malloc(*n * sizeof(int));  //每个数据点所属聚类的标志数组
    for(i=0;i<*n;i++)
        for(j=0;j<*d;j++)
            fscanf(fp,"%f",&arraydata[i][j]);  //读取数据点
    return arraydata;
}
float **loadData2(int *k,int *d,int *n)
{
    int i,j;
    float **arraydata;
    FILE *fp;
    if((fp=fopen("txt2.txt","r"))==NULL)    fprintf(stderr,"cannot open data.txt!\n");
    if(fscanf(fp,"K=%d,D=%d,N=%d\n",k,d,n)!=3)        fprintf(stderr,"load error!\n");
    arraydata=array(*n,*d);  //生成数据数组
    cluster_center=array(*k,*d);  //聚类的中心点
    in_cluster=(int *)malloc(*n * sizeof(int));  //每个数据点所属聚类的标志数组
    for(i=0;i<*n;i++)
        for(j=0;j<*d;j++)
            fscanf(fp,"%f",&arraydata[i][j]);  //读取数据点
    return arraydata;
}
//计算数据点到聚类中心的距离份额
/**float getDistance()
{
    int i,j;
    float S;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            S+=pow(data[i][j]-cluster_center[i][j]);
        }
    }
    return S;
}**/
float s1(){
    int i,j;
    int q=0;
    float S;
    float x0,y0,z0;
    float **D0;
    float sum0[2][2];
    float Xs0[2][2];
    float Ys0[2][2];
    //srand((unsigned int)(time(NULL)));  //随机初始化k个中心点
    //b0=1.0;//b0   
    data=loadData1(&K,&D,&N);
     for(i=0;i<N;i++){
        for(j=0;j<D;j++){
            printf("%f",data[i][j]);
            if((j+1)%D==0)    putchar('\n');
        }
        }
    //导入三元组所需值
    FILE *p;
    p=fopen("file.txt", "r");
        fscanf(p, "%f%f%f", &x0, &y0, &z0);
        printf("read:\nx0=%f, y0=%f, z0=%f\n", x0, y0, z0);
        //fscanf(p, "%f%f%f", &io.x0, &io.y0, &io.z0);
        //printf("read:\nx0=%f, y0=%f, z0=%f\n", io.x0, io.y0, io.z0);
        fclose(p);
    io.Sz0=z0;
    //用户给定聚类中心份额
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            cluster_center[i][j]=data[i][j]-0.1;
            printf("%f\n",cluster_center[i][j]);
            }
            }    

    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        Xs0[i][j] = data[i][j]-cluster_center[i][j];//Xs0=a0-c0
        printf("1:%f\n",Xs0[i][j]);
        }
    }
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        io.D0[q]=Xs0[i][j];
        printf("D0:%f\n",io.D0[q]);
        q++;
        }
        }    
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        Xs0[i][j] = Xs0[i][j]-b0;//Xs0=Xs0-b0
        printf("b0:%f\n",b0);
        printf("2:%f\n",Xs0[i][j]);
        io.Sx0[q]=Xs0[i][j];
        printf("Sx0:%f\n",io.Sx0[q]);
        q++;
        }
    }
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        Ys0[i][j] = b1;
        printf("3:%f\n",Ys0[i][j]);
        io.Sy0[q]=Ys0[i][j];
        printf("Sy0:%f\n",io.Sy0[q]);
        q++;
        }
    }//Ys0=b1
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            io.Xs00[i][j] = Xs0[i][j]-x0;//x0
            io.Ys00[i][j]=Ys0[i][j]-y0;//y0
            printf("Xs00:%f\n",io.Xs00[i][j]);
            printf("Ys00:%f\n",io.Ys00[i][j]);
            /**io.S0x0[1]=io.Xs00[i][j];
            io.S0y0[1]=io.Ys00[i][j];
            printf("S0x0:%f\n",io.S0x0[1]);
            printf("S0y0:%f\n",io.S0y0[1]);
            p++;**/
        }
    }
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        io.S0x0[q]=io.Xs00[i][j];
        io.S0y0[q]=io.Ys00[i][j];
        printf("S0x0:%f\n",io.S0x0[q]);
        printf("S0y0:%f\n",io.S0y0[q]);
        q++;
        }
        }
    /**for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            Xs[i][j]=Xs0[i][j]+Xs1[i][j];//x=x0+x1
            Ys[i][j]=Ys0[i][j]+Ys1[i][j];//y=y0+y1
    printf("bbb\n");
        }
    }

    
    
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            D0[i][j]=z0+Xs[i][j]*Ys0[i][j]+Ys[i][j]*Xs0[i][j];
    printf("ccc\n");
        }
    }
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            S=1;
            sum0[i][j]=S+2*D0[i][j];
                printf("ddd\n");

        }
    }**/
    printf("a");	

}
float s2(){
    int i,j,q=0;
    float S;
    float x1,y1,z1;
    float **D1;
    float **sum1;
    //srand((unsigned int)(time(NULL)));  //随机初始化k个中心点
    //io.b1=1.0;//b1
    for(i=0;i<K;i++){
    	for(j=0;j<D;j++){
    	cluster_center[i][j]=0;
    	}
    }
    data=loadData2(&K,&D,&N);
      for(i=0;i<N;i++){
        for(j=0;j<D;j++){
            printf("%f",data[i][j]);
            if((j+1)%D==0)    putchar('\n');
        }
        }

    //导入三元组所需值
    FILE *p;
    p=fopen("file.txt", "r");
    int x,y,z;
        fscanf(p, "%f%f%f", &x1, &y1, &z1);
        printf("read:\nx1=%f, y1=%f, z1=%f\n", x1, y1, z1);
        fclose(p);
    io.Sz1=z1;
    //用户给定聚类中心份额
    for(i=0;i<K;i++){
        for(j=0;j<2;j++){
            cluster_center[i][j]=data[i][j]-0.1;
            printf("0:%f\n",cluster_center[i][j]);
            }
            }
    //getDistance(D);//S->D1

    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        Ys1[i][j] = data[i][j]-cluster_center[i][j];//Ys1=a0-c1
        printf("1:%f\n",Ys1[i][j]);
        }
    }
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        io.D1[q]=Ys1[i][j];
        printf("D1:%f\n",io.D1[q]);
        q++;
        }
        }    
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        Ys1[i][j] = Ys1[i][j]-b1;//Ys1=Ys1-b1
        printf("2:%f\n",Ys1[i][j]);
        io.Sx1[q]=Ys1[i][j];
        printf("Sx1:%f\n",io.Sx1[q]);
        }
    }
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        Xs1[i][j] = b0;
        printf("b0:%f\n",b0);
        printf("3:%f\n",Xs1[i][j]);
        io.Sy1[q]=Xs1[i][j];
        printf("Sy1:%f\n",io.Sy1[q]);        
        }
    }//Xs1=b1

    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            io.Xs11[i][j]=Xs1[i][j]-x1;//x1
            io.Ys11[i][j]=Ys1[i][j]-y1;//y1
            printf("io.Xs11:%f\n",io.Xs11[i][j]);
            printf("io.Ys11:%f\n",io.Ys11[i][j]);
        }
    }
    q=0;
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
        io.S1x1[q]=io.Xs11[i][j];
        io.S1y1[q]=io.Ys11[i][j];
        printf("S1x1:%f\n",io.S1x1[q]);
        printf("S1y1:%f\n",io.S1y1[q]);
        q++;
        }
        }
    /**for(i=0;i<K;i++){
        for(j=0;i<D;i++){
        Xs[i][j]=Xs0[i][j]+Xs1[i][j];
        Ys[i][j]=Ys0[i][j]+Ys1[i][j];
       printf("ccc\n");     
        }
    }
    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            D1[i][j]=z1+Xs[i][j]*Ys1[i][j]+Ys[i][j]*Xs1[i][j]-Xs[i][j]*Ys[i][j];
    		printf("ccc\n");
        }
    }

    for(i=0;i<K;i++){
        for(j=0;j<D;j++){
            S=1;
            sum1[i][j]=S+2*D1[i][j];
                   printf("ccc\n");
        }
    }**/
   printf("b"); 

}
